home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Megadoom II
/
MEGADOOM II - iso.7z
/
MEGADOOM II.ISO
/
doom
/
network
/
serial6
/
sersetup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-21
|
54KB
|
2,258 lines
// sersetup.c
// Created by Id Software for SERSETUP.EXE, 1993, 1994.
// Hacked by Russell Gilbert and others SER4.EXE, SER5.EXE, and SER6.EXE 1994.
// Hacked by Paul T. Hermann for SER5.EXE, SER6.EXE 1994.
//
// Compiled under Borland C++ 3.1 using the Compact Memory module
// Using 80386 instruction set and 80387 emualation support
// Optimizations for speed enabled
//
#include "sersetup.h"
#include "DoomNet.h"
#include <time.h>
#include <dirent.h>
#include <io.h>
#define PROG_NAME "SER6"
#define PROG_EXE "SER6.EXE"
#define PROG_CONFIG "SER6.CFG"
extern que_t inque;
extern que_t outque;
extern int uart_type;
int rgstrncpy (char *, char *, int );
int getwadlevel ( char * );
void pickdirectory ( void );
void pickwads ( void );
int sort_function (const void *a, const void *b);
void parsewad ( char * , char * );
int checkwad ( int , char * );
void kill_nonwads ( void );
int SendFile ( void );
int ReceiveFile (char *);
void dir ( int );
void pause (void);
void DOOM (void);
void jump_start( void );
void GetUart (void);
void ModemCommand (char *str);
int ModemResponse (char *resp);
void configure (void);
void reset_counters (void);
int usemodem = FALSE;
time_t starttime = 0;
time_t endtime = 0;
time_t playtime = 0;
char init1 [80+1];
char init2 [80+1];
char altbaudinit [80+1];
int use_altbaudinit = FALSE;
char hangup [80+1];
char config [80+1];
char devparm [256+1];
char directory [39+1];
char wadname [21][12+1];
char add [50+1];
char doomexe[12+1];
char levels[32][5+1];
char dial [50+1];
unsigned long baud = 9600;
unsigned long altbaud = 9600;
int comport = 1;
int irq = -1;
int uart = -1;
int nodropdtr = 0;
int vector = -1;
int loadgame = -1;
int episode = -1;
int map = -1;
int skill = -1;
int deathmatch = 0;
int altdeath = 0;
int pulsedial = 0;
int player = 0;
int nomonsters = 0;
int respawn = 0;
int doomver1_2 = 0;
int doom2 = 0;
/* showReadStats() counters. */
unsigned long writeBufferOverruns = 0;
unsigned long bytesRead = 0;
unsigned long packetsRead = 0;
unsigned long largestReadPacket = 0;
unsigned long smallestReadPacket = 0xFFFFFFFFl;
unsigned long readBufferOverruns = 0;
unsigned long totalReadPacketBytes = 0;
unsigned long oversizeReadPackets = 0;
unsigned long largestOversizeReadPacket = 0;
unsigned long overReadPacketLen = 0;
/* showWriteStats() counters. */
unsigned long bytesWritten = 0;
unsigned long packetsWrite = 0;
unsigned long largestWritePacket = 0;
unsigned long smallestWritePacket = 0xFFFFFFFFl;
unsigned long totalWritePacketBytes = 0;
unsigned long oversizeWritePackets = 0;
unsigned long largestOversizeWritePacket = 0;
/* showUartErrors() counters. */
unsigned long numBreak = 0;
unsigned long numFramingError = 0;
unsigned long numParityError = 0;
unsigned long numOverrunError = 0;
unsigned long numTxInterrupts = 0;
unsigned long numRxInterrupts = 0;
void showReadStats()
{
if ( smallestReadPacket == 0xFFFFFFFFl )
smallestReadPacket = 0;
printf ("Read statistics:\n");
printf ("%9lu Largest packet %9lu Smallest packet\n",
largestReadPacket, smallestReadPacket);
printf ("%9lu Oversize packets %9lu Largest oversize packet\n",
oversizeReadPackets, largestOversizeReadPacket);
printf ("%9lu Total packets %9lu Buffer overruns\n",
packetsRead, readBufferOverruns);
printf ("%9lu Total bytes %9.1f Average bytes/minute\n",
totalReadPacketBytes,
starttime == 0 || playtime == 0 ? 0 :
(float) totalReadPacketBytes / (float) ((float) playtime / 60));
printf ("%9lu Receive interrupts %9.1f Average bytes/interrupt\n",
numRxInterrupts,
numRxInterrupts == 0 ? 0 :
(float) totalReadPacketBytes / (float) numRxInterrupts);
printf ("\n");
}
void showWriteStats()
{
if ( smallestWritePacket == 0xFFFFFFFFl )
smallestWritePacket = 0;
printf ("Write statistics:\n");
printf ("%9lu Largest packet %9lu Smallest packet\n",
largestWritePacket, smallestWritePacket);
printf ("%9lu Oversize packets %9lu Largest oversize packet\n",
oversizeWritePackets, largestOversizeWritePacket);
printf ("%9lu Total packets %9lu Buffer overruns\n",
packetsWrite, writeBufferOverruns);
printf ("%9lu Total bytes %9.1f Average bytes/minute\n",
totalWritePacketBytes,
starttime == 0 || playtime == 0 ? 0 :
(float) totalWritePacketBytes / (float) ((float) playtime / 60));
printf ("%9lu Transmit interrupts %9.1f Average bytes/interrupt\n",
numTxInterrupts,
numTxInterrupts == 0 ? 0 :
(float) totalWritePacketBytes / (float) numTxInterrupts);
printf ("\n");
}
void showUartErrors()
{
printf ("UART line status\n");
printf ("%9lu Breaks detected %9lu Framing errors\n",
numBreak, numFramingError);
printf ("%9lu Parity errors %9lu Overrun errors\n",
numParityError, numOverrunError);
}
/*
================
=
= write_buffer
=
================
*/
void write_buffer( char *buffer, unsigned int count )
{
// if this would overrun the buffer, throw everything else out
if (outque.size + count > QUESIZE)
{
++writeBufferOverruns;
outque.tail = outque.head;
outque.size = 0;
}
while (count--)
write_byte (*buffer++);
if ( INPUT( uart + LINE_STATUS_REGISTER ) & 0x40)
jump_start();
}
void hangup_modem (void)
{
if (nodropdtr == 1)
printf("\nLeaving DTR up!\n");
else
{
printf ("\n");
printf ("\nDropping DTR\n");
OUTPUT( uart + MODEM_CONTROL_REGISTER
, INPUT( uart + MODEM_CONTROL_REGISTER ) & ~MCR_DTR );
delay (1250);
OUTPUT( uart + MODEM_CONTROL_REGISTER
, INPUT( uart + MODEM_CONTROL_REGISTER ) | MCR_DTR );
ModemCommand("+++");
delay (1250);
if (hangup [0] != EOS)
ModemCommand(hangup);
else
{
printf ("Warning: No HANGUP= string in config file. Using default.\n");
ModemCommand("ATH0");
}
delay (1250);
while (read_byte () != -1)
;
}
}
/*
=================
=
= Error
=
= For abnormal program terminations
=
=================
*/
void Error (char *error, ...)
{
va_list argptr;
if (usemodem)
hangup_modem ();
ShutdownPort ();
if (vectorishooked)
setvect (doomcom.intnum,olddoomvect);
if (error)
{
va_start (argptr,error);
vprintf (error,argptr);
va_end (argptr);
printf ("\n\n");
}
exit (error != (char *) NULL);
}
/*
================
=
= ReadPacket
=
================
*/
#define MAXPACKET 512
#define FRAMECHAR 0x70
char packet[MAXPACKET];
int packetlen;
int inescape;
int newpacket;
boolean ReadPacket (void)
{
int c;
// if the buffer has overflowed, throw everything out
if (inque.size > QUESIZE - 4) // check for buffer overflow
{
++readBufferOverruns; /* Count read overruns */
inque.tail = inque.head;
inque.size = 0;
newpacket = true;
return false;
}
if (newpacket)
{
packetlen = 0;
newpacket = 0;
overReadPacketLen = 0;
}
while ( 1 )
{
if ((c = read_byte ()) < 0)
return false; // haven't read a complete packet
if (inescape)
{
inescape = false;
if (c != FRAMECHAR)
{
newpacket = 1;
++packetsRead; /* Count packets read */
if ( packetlen > largestReadPacket ) /* Track largest packet */
largestReadPacket = packetlen;
if ( packetlen < smallestReadPacket ) /* Track smallest packet */
smallestReadPacket = packetlen;
totalReadPacketBytes += packetlen; /* Count total packet bytes */
return true; // got a good packet
}
}
else if (c == FRAMECHAR)
{
inescape = true;
continue; // don't know yet if it is a terminator
} // or a literal FRAMECHAR
if (packetlen >= MAXPACKET)
{
++overReadPacketLen; /* Keep track of size of oversize packet */
oversizeReadPackets++; /* Count oversize packets */
if ( overReadPacketLen > largestOversizeReadPacket )
largestOversizeReadPacket = overReadPacketLen;
continue; // oversize packet
}
packet[packetlen] = c;
packetlen++;
}
}
/*
=============
=
= WritePacket
=
=============
*/
void WritePacket (char *buffer, int len)
{
int b;
char static localbuffer[MAXPACKET*2+2];
b = 0;
if (len > MAXPACKET)
{
++oversizeWritePackets; /* Count oversize write packets */
if ( len > largestOversizeWritePacket )
++largestOversizeWritePacket;
return;
}
if ( len > largestWritePacket )
largestWritePacket = len;
if ( len < smallestWritePacket )
smallestWritePacket = len;
totalWritePacketBytes += len;
++packetsWrite;
while (len--)
{
if (*buffer == FRAMECHAR)
localbuffer[b++] = FRAMECHAR; // escape it for literal
localbuffer[b++] = *buffer++;
}
localbuffer[b++] = FRAMECHAR;
localbuffer[b++] = 0;
write_buffer (localbuffer, b);
}
/*
=============
=
= NetISR
=
=============
*/
void interrupt NetISR (void)
{
if (doomcom.command == CMD_SEND)
WritePacket ((char *)&doomcom.data, doomcom.datalength);
else if (doomcom.command == CMD_GET)
{
if (ReadPacket () && packetlen <= sizeof(doomcom.data) )
{
doomcom.remotenode = 1;
doomcom.datalength = packetlen;
memcpy (&doomcom.data, &packet, packetlen);
}
else
doomcom.remotenode = -1;
}
}
/*
=================
=
= Connect
=
= Figures out who is player 0 and 1
=================
*/
int Connect (void)
{
struct time time;
int oldsec;
int localstage, remotestage;
char str[10];
//
// wait for a good packet
//
printf ("Attempting to connect across serial link, press escape to abort.\n");
doomcom.consoleplayer = player;
oldsec = -1;
localstage = remotestage = 0;
inque.tail = inque.head; //clears the buffer.
inque.size = 0;
newpacket = TRUE;
while (remotestage < 4)
{
while ( bioskey(1) )
{
if ( (bioskey (0) & 0xff) == ESC)
{
printf ("\n\nSerial game synchronization aborted.\n");
while (read_byte () != -1);
return FALSE;
}
}
if (ReadPacket ())
{
packet[packetlen] = 0;
printf ("read: '%s'\n", packet);
if (packetlen != 7)
{
printf ("bad packet len = %d (should be 7)\n", packetlen);
continue;
}
if (strncmp(packet,"PLAY",4) )
{
printf ("error: first 4 char's aren't 'PLAY'\n");
continue;
}
remotestage = packet[6] - '0';
localstage = remotestage+1;
if (packet[4] == '0'+doomcom.consoleplayer)
{
doomcom.consoleplayer ^= 1;
localstage = remotestage = 0;
}
oldsec = -1;
}
gettime (&time);
if (time.ti_sec != oldsec)
{
oldsec = time.ti_sec;
sprintf (str,"PLAY%i_%i",doomcom.consoleplayer,localstage);
WritePacket (str,strlen(str));
printf ("wrote: '%s'\n",str);
}
}
while (ReadPacket ()) // flush out any extras
;
return TRUE;
}
/*
==============
=
= ModemCommand
=
==============
*/
void ModemCommand (char *str)
{
int i;
char *ptr;
printf ("Modem command : %s\n",str);
ptr = str;
for (i = 0; i < strlen (str); i++)
{
write_buffer (ptr++, 1);
delay (20);
}
write_buffer ("\r",1);
}
/*
==============
=
= ModemResponse
=
= Waits for OK, RING, CONNECT, etc
==============
*/
int ModemResponse (char *resp)
{
int c;
int respptr;
char response[80];
do
{
printf ("Modem response: ");
respptr=0;
while (1)
{
while ( bioskey(1) )
{
if ( (bioskey (0) & 0xff) == ESC)
{
printf ("\nModem response aborted.\n");
hangup_modem ();
return FALSE;
}
}
c = read_byte ();
if (c==-1)
continue;
if (c=='\n' || respptr == 79)
{
response[respptr] = 0;
printf ("%s\n",response);
break;
}
if (c >= ' ')
{
response[respptr] = c;
respptr++;
}
}
}while (strncmp(response,resp,strlen(resp)));
return TRUE;
}
/*
=============
=
= InitModem
=
=============
*/
void InitModem (void)
{
if (init1 [0] != EOS)
{
ModemCommand (init1);
if (! ModemResponse ("OK"))
return;
}
if (init2 [0] != EOS)
{
ModemCommand (init2);
if ( !ModemResponse ("OK"))
return;
}
if (use_altbaudinit == TRUE && altbaudinit [0] != EOS)
{
ModemCommand (altbaudinit);
if ( !ModemResponse ("OK"))
return;
}
}
void alt_init (void)
{
int ch;
printf ("\nUse %lu baud and init string '%s'? (y/n): ",
altbaud, altbaudinit);
if ((ch = getch()) == 'y' || ch == 'Y')
{
use_altbaudinit = TRUE;
baud = altbaud;
InitPort(); //Re-inits the port with new baud rate.
printf (
"\n\nPort re-initialized. Alternate init string will be used for dial and answer.\n\n");
pause ();
}
printf ("\n");
}
/*
=============
=
= Dial_Modem
=
=============
*/
int Dial_Modem (void)
{
char cmd[80];
int ch;
char line [50];
FILE *infile;
int found_name = FALSE;
int prompt = TRUE;
char buf [50];
usemodem = true;
InitModem ();
if (dial [0] != EOS)
{
printf ("\nDial %s? (y/n): ", dial);
if ((ch = getch()) == 'y' || ch == 'Y')
prompt = FALSE;
}
if (prompt)
{
printf ("\nEnter number to dial or phonebook name: ");
gets (line);
if (sscanf (line, "%s", dial) == EOF)
return FALSE;
if ((infile = fopen (PROG_CONFIG, "r")) == NULL)
{
sprintf (buf, "Couldn't read file %s.\n", PROG_CONFIG);
Error (buf);
}
while (fgets (line, 256, infile) != NULL)
{
if (line [0] == 'N' && line [1] == 'A')
{
/* NAME */
if (strncmp (&line [5], dial, strlen (dial)) == 0)
found_name = TRUE;
}
else if (found_name && line [0] == 'N' && line [1] == 'U')
{
/* NUMBER */
sscanf (&line [7], "%s", dial);
break; // Found a number break out and dial
}
}
fclose (infile);
}
printf ("\nDialing %s\n\n", dial);
if (pulsedial)
sprintf (cmd,"ATDP%s", dial);
else
sprintf (cmd,"ATDT%s", dial);
ModemCommand(cmd);
return ModemResponse ("CONNECT");
}
/*
=============
=
= Answer
=
=============
*/
int Answer (void)
{
usemodem = true;
InitModem ();
printf ("\nWaiting for ring...\n\n");
if (! ModemResponse ("RING"))
return FALSE;
ModemCommand ("ATA");
return ModemResponse ("CONNECT");
}
int rgstrncpy (char *dest, char *src, int max)
{
int i = 0;
char *srcptr;
char *destptr;
/* Just like strncpy(), but force a null at the end regardless of
* whether we copied the max # of characters or not.
*/
srcptr = src;
destptr = dest;
while (i < max)
{
if ((*destptr++ = *srcptr++) == EOS)
break;
++i;
}
if (i == max)
dest [max-1] = EOS;
return i;
}
void get_config_settings (void)
{
char line [80+1];
char space[]=" ";
int len;
FILE *infile;
int i;
unsigned char far *vectorptr;
unsigned long lnum;
char buf [50];
if ((infile = fopen (PROG_CONFIG, "r")) == NULL)
{
sprintf (buf, "Couldn't read %s file.", PROG_CONFIG);
Error (buf);
}
while (fgets (line, 81, infile) != NULL)
{
if (line [(len = strlen (line))-1] == '\n') /* Get rid of cr at end */
line [len-1] = EOS;
switch (line [0])
{
case 'A' :
if (line[3] == 'D')
{ /* ALTDEATH */
sscanf (&line [9], "%d", &altdeath);
}
else if (line [7] == 'I')
{ /* ALTBAUDINIT */
if ( line[12] != EOS )
rgstrncpy (altbaudinit, &line [12], 80+1);
}
else if (line [3] == 'B')
{ /* ALTBAUD */
if (sscanf (&line [8], "%lu", &altbaud) != EOF &&
altbaud != 9600 && altbaud != 14400 && altbaud != 19200 &&
altbaud != 38400 && altbaud != 57600 && altbaud != 115200)
{
altbaud = 9600;
}
}
break;
case 'B' :
/* BAUD */
if (sscanf (&line [5], "%lu", &baud) != EOF &&
baud != 9600 && baud != 14400 && baud != 19200 &&
baud != 38400 && baud != 57600 && baud != 115200)
{
baud = 9600;
}
break;
case 'C' :
if (line [3] == 'F')
{
/* CONFIG */
rgstrncpy (config, &line [7], 80+1);
}
else
{
/* COM */
sscanf (&line [4], "%d", &comport);
}
break;
case 'D' :
if (line [2] == 'V')
{
/* DEVPARM */
rgstrncpy (devparm, &line [8], 256+1);
if (strncmpi(devparm, "-f", 2) != 0 && devparm[0] != EOS)
{
rgstrncpy (add, devparm, 50);
strcat(add, space);
}
}
else if (line [3] == 'L')
{
/* DIAL */
rgstrncpy (dial, &line [5], 50+1);
}
else if (line [2] == 'R')
{
/* DIRECTORY */
if (rgstrncpy (directory, &line [10], 40+1) > 0)
{
if (directory[(len = strlen (directory))-1] != ':'
&& directory[len-1] != '\\')
{
directory [len] = '\\';
directory [len+1] = EOS;
}
}
else
strcpy (directory, ".\\");
}
else if (line [3] == 'T')
{
/* DEATHMATCH */
sscanf (&line [11], "%d", &deathmatch);
}
else if (line [5] == 'X')
{
/* DOOMEXE */
rgstrncpy (doomexe, &line [8], 12+1);
}
else if (line [4] == '2')
{ /* DOOM2 */
sscanf (&line [6], "%d", &doom2);
}
else if (line [4] == 'V')
{
/* DOOMVER1_2 */
sscanf (&line [11], "%d", &doomver1_2);
}
break;
case 'E' :
/* EPISODE */
sscanf (&line [8], "%d", &episode);
break;
case 'H' :
/* HANGUP */
rgstrncpy (hangup, &line [7], 80+1);
break;
case 'I' :
if (line [1] == 'N')
{
if (line [4] == '1')
{
/* INIT1 */
rgstrncpy (init1, &line [6], 80+1);
}
else
{
/* INIT2 */
rgstrncpy (init2, &line [6], 80+1);
}
}
else
{
/* IRQ */
sscanf (&line [4], "%d", &irq);
}
break;
case 'L' :
/* LOADGAME */
sscanf (&line [9], "%d", &loadgame);
break;
case 'M' :
/* MAP */
sscanf (&line [4], "%d", &map);
break;
case 'N' :
if (line [3] == 'O')
{
/* NOMONSTERS (as opposed to NAME or NUMBER) */
sscanf (&line [11], "%d", &nomonsters);
}
else if (line [3] == 'R')
{
/* NODROPDTR */
sscanf (&line [10], "%d", &nodropdtr);
}
break;
case 'P' :
if (line [1] == 'O')
{
/* PORT */
sscanf (&line [5], "0x%x", &uart);
}
else if (line [1] == 'L')
{
/* PLAYER */
sscanf (&line [7], "%d", &player);
if (player < 0 || player > 1)
player = 0;
}
else
{
/* PULSEDIAL */
sscanf (&line [10], "%d", &pulsedial);
}
break;
case 'R' :
/* RESPAWN */
sscanf (&line [8], "%d", &respawn);
break;
case 'S' :
/* SKILL */
sscanf (&line [6], "%d", &skill);
break;
case 'V' :
/* VECTOR */
sscanf (&line [7], "0x%x", &vector);
break;
case 'W' :
/* WADNAME */
rgstrncpy (wadname [0], &line [8], 12+1);
break;
}
}
fclose (infile);
if ( doomexe[0] == EOS )
{
if (doom2)
strcpy(doomexe, "DOOM2");
else
strcpy(doomexe, "DOOM");
}
/* Get irq and uart if not already set */
if (irq == -1 || uart == -1)
GetUart ();
/* Get an interrupt vector if not already set */
if (vector == -1)
{
for (vector = 0x60 ; vector <= 0x66 ; vector++)
{
vectorptr = *(unsigned char far * far *)(vector*4);
if ( !vectorptr || *vectorptr == 0xcf )
break;
}
if (vector == 0x67)
{
printf ("Warning: no NULL or iret interrupt vectors were found in the 0x60 to 0x66\n");
printf ("range. You can specify a vector with the VECTOR=0x<num> line in %s.\n\n", PROG_CONFIG);
pause ();
vector = 0x66;
}
}
doomcom.intnum = vector;
}
void print_config_settings (void)
{
clrscr ();
printf (" Port settings (%s-type UART detected):\n\n",
uart_type == UART_8250 ? "8250" : "16550");
printf ("INIT1=%.73s\n", init1);
printf ("INIT2=%.73s\n", init2);
printf ("HANGUP=%.72s\n", hangup);
printf ("BAUD=%-6lu\n", baud);
printf ("COM=%d\n", comport);
printf ("IRQ=%d\n", irq);
printf ("PORT=0x%x\n", uart);
printf ("NODROPDTR=%d\n", nodropdtr);
printf ("\n DOOM settings: ");
textcolor(RED);
if (doom2)
cprintf("DOOM ][: Hell on Earth\r\n\n");
else
cprintf("DOOM I\r\n\n");
textcolor(LIGHTGRAY);
if (doom2)
printf ("EPISODE=n/a ");
else
printf ("EPISODE=%d ", episode == -1 ? 1 : episode);
printf ("MAP=%d\n", map == -1 ? 1 : map);
printf ("DEATHMATCH=%d ALTDEATH=%d\n", deathmatch, altdeath);
printf ("NOMONSTERS=%d RESPAWN=%d\n", nomonsters, respawn);
printf ("LOADGAME=%c DEVPARM=%.50s\n",
loadgame == -1 ? ' ' : loadgame + '0',
devparm);
printf ("SKILL=%d DIAL=%.50s\n",
skill == -1 ? 3 : skill,
dial);
printf ("WADNAME=%-12.12s DIRECTORY=%.39s\n", wadname [0], directory);
printf ("DOOMEXE=%-12.12s CONFIG=%.51s\n", doomexe, config);
printf ("DOOMVER1_2=%d PULSEDIAL=%d\n", doomver1_2, pulsedial);
printf ("PLAYER=%d VECTOR=0x%x\n", player, vector);
}
void configure (void)
{
char line [256];
char files [256];
char space[]=" ";
int i = 0;
int j = 0;
int xpos;
int ypos;
clrscr ();
printf ("Configure... Press ENTER to keep current value shown in [].\n\n");
printf (" Wadfile directory [%s]: ", directory);
pickdirectory ();
printf ("\n");
pickwads ();
if (wadname [0][0] != EOS) // Clear devparm for new wad files
devparm [0] = EOS;
files[0]=EOS;
while(wadname[i][0] != EOS)
{
if (checkwad (i, wadname[i]) != FALSE) // Check for wadfile existance , allow missing wads to remain
strcat(files,devparm); // put all files into 1 string
else if (i == 0)
wadname [0][0] = EOS;
i++;
}
if (wadname [0][0] != EOS) // Construct file arguments into the devparm line
sprintf(devparm,"%s-file%s\0",add,files); // places devparm stuff first
else
strcpy(devparm,add);
if ((wadname[0] == EOS) && (add [0] == EOS))
devparm [0] = EOS;
/* Prints the previous Devparm strings in a neat way */
cprintf ("\r\n Doom switches (-1 to Clear, \"+-switch\" to add, \"-switch\" to change)\r\n"
" (This only changes Misc. switches)\r\n");
cprintf (" Misc. [");
cprintf("]\r\n Pwads [");
xpos=wherex();
ypos=wherey();
printf("]");
gotoxy(xpos,ypos-1);
i=0;
while (devparm[i] != EOS) /* Displays previous arguments */
{
if ( (devparm[i] == '-') && (devparm[i+1] == 'f') )
{
cprintf("]"); //moves to the File section of the display
gotoxy(xpos,ypos);
}
if ( (devparm[i] == ' ') && (devparm[i-4] == '.') )
if (++j == 2) //Allows 2 Pwads displayed per line
{
j=0;
ypos++;
cprintf("]\r\n [ ");
}
cprintf ("%c",devparm[i++]);
}
cprintf("]");
gotoxy(1,ypos+1);
cprintf(" ??? : ");
gets (line);
if (strcmp (line, "-1") == 0)
{
add [0] = EOS;
if (files[0] != EOS)
sprintf(devparm,"-file%s", files); //resets devparm to just files
else
devparm[0]=EOS;
printf("\nNew Misc. Options: (none)\n"); //redisplay options
}
else if (line [0] == '+')
{
strcat (add, &line[1]); //Removes the "+"
strcat (add, space);
if (files[0] != EOS)
sprintf(devparm, "%s-file%s", add, files); //Places additional stuff first
else
strcpy(devparm, add);
line [0] = EOS;
printf("\nNew Misc. Options: %s\n",add); //redisplay options
}
else if (line [0] != EOS) //Completely new additional stuff
{
sprintf(add,"%s ", line);
if (files[0] != EOS)
sprintf(devparm,"%s-file%s", add, files);
else
strcpy(devparm, add);
printf("\nNew Misc. Options: %s\n",add); //redisplay options
}
printf ("\n");
printf (" deathmatch (0/1) [%d]: ", deathmatch);
gets (line);
sscanf (line, "%d", &deathmatch);
if (deathmatch == 1)
{
printf (" altdeath (0/1) [%d]: ",altdeath);
gets (line);
sscanf (line, "%d", &altdeath);
}
else
altdeath = 0;
printf (" nomonsters (0/1) [%d]: ", nomonsters);
gets (line);
sscanf (line, "%d", &nomonsters);
printf (" respawn (0/1) [%d]: ", respawn);
gets (line);
sscanf (line, "%d", &respawn);
if (!doom2) //Doom 2 doesn't have episodes
{
printf (" episode (1-3) [%d]: ", episode == -1 ? 1 : episode);
gets (line);
sscanf (line, "%d", &episode);
if (episode < 2 || episode > 3) /* If default, set back to -1 */
episode = -1;
}
printf (" map (1-32) [%d]: ", map == -1 ? 1 : map);
gets (line);
sscanf (line, "%d", &map);
if (map < 2 || map > 32) /* If default, set back to -1 */
map = -1;
printf (" skill (1-5) [%d]: ", skill == -1 ? 3 : skill);
gets (line);
sscanf (line, "%d", &skill);
if (skill < 1 || skill > 5 || skill == 3) /* If default, set back to -1 */
skill = -1;
printf (" loadgame (0-5 or -1) [%c]: ", loadgame == -1 ? ' ' : loadgame + '0');
gets (line);
sscanf (line, "%d", &loadgame);
if (loadgame < 0 || loadgame > 5)
loadgame = -1;
printf( " player Num. (0 or 1) [%d]: ", player);
gets(line);
sscanf (line, "%d", &player);
if (player < 0 || player > 1)
player = 0;
printf("\n");
}
void pickdirectory (void)
{
char line [40];
char *p;
line[0]=39; //Limit to 38 chars + null
p=cgets (line);
strcpy(line, p);
if (strcmp (line, "-1") == 0)
directory [0] = EOS;
else if (line [0] != EOS )
{
if( (line [strlen(line) - 1] != ':') && (line [strlen(line) -1] != '\\') )
sprintf(directory, "%s\\", line);
else
strcpy (directory, line);
}
}
void printselected ( int xpos)
{
int i=0;
int ypos;
ypos=wherey();
while (wadname [i][0] != EOS) /* Displays previous arguments */
{
if ( (wherex() + strlen(wadname[i])) > 78 ) //avoids line wrapping
{
cprintf("]\r\n");
ypos=wherey();
gotoxy(xpos,ypos);
cprintf("[");
}
cprintf ("%s, ",wadname[i++]);
}
if ( i == 0 ) cprintf("]");
else cprintf("\b\b]");
ypos=wherey();
gotoxy(xpos-4, ypos+1);
cprintf("??? :");
}
void pickwads (void)
{
char line [100];
char ext[]=".WAD";
kill_nonwads();
wadname[9][0]=EOS; //Limit to 9 Pwads in configure
cprintf ("\r\n Enter Pwads to play (-1 to clear, separate wads with a \"space\")\r\n"
" Names (9 MAX) [");
printselected(18);
gets (line);
if (strcmp (line, "-1") == 0)
{
wadname [0][0] = EOS;
strcpy (devparm, add);
}
else if (line [0] != EOS) // Parse multiple wads
parsewad( line, ext);
}
void parsewad (char *line, char *ext)
{
int i=0;
char *ptr;
for (i = 0; i < 9; i++)
{
if ((ptr = strtok (i == 0 ? line : NULL, " ")) == NULL)
{
wadname [i][0] = EOS;
return;
}
strcpy (wadname [i], ptr);
if (strlen (wadname [i]) > 4)
{
if (strncmpi (
&wadname [i][strlen (wadname [i]) - 4], ext, strlen (ext)) == 0)
{
/* Wad name already ends in given extension, so don't add it. */
continue;
}
}
/* Wad name doesn't end in given extension already, so add it. */
strcat (wadname [i], ext);
}
}
int checkwad ( int numwad, char *wad )
{
char junk [55];
int tempmapnum;
int j=0;
sprintf(junk,"%s%s\0",directory,wad);
if (getwadlevel( junk) == TRUE)
{
while (levels[j][0] != EOS)
{
if (numwad == 0) map = 32;
if (doom2)
sscanf (&levels[j][3], "%d%d", &tempmapnum);
else
sscanf (&levels[j][3], "%d", &tempmapnum);
if ( tempmapnum < map )
{
map=tempmapnum;
if (!doom2)
sscanf (&levels[j][1], "%d", &episode);
textcolor(YELLOW);
if (doom2) // Doom 2 has no episode number
cprintf(" Setting to Map %d\r\n",map);
else
cprintf(" Setting to Episode %d, Map %d\r\n",episode,map);
textcolor(LIGHTGRAY);
numwad++;
}
j++;
}
}
else if ( getwadlevel ( junk) == 2)
{
printf("\a\nFile %s does not exist.\n\n",junk);
sprintf(devparm," %s",junk);
return 2; // Nonexist file
}
else
{
printf("\a\nWadfile, %s, is corrupted\n",junk);
return FALSE;
}
sprintf(devparm," %s",junk);
return TRUE;
}
int getwadlevel ( char *wadname)
{
FILE *WadFile;
char pwad[6];
long dirstart;
int direntries;
int i=0;
int j=0;
char name[17];
if ((WadFile = fopen(wadname, "rb")) == NULL)
return 2; // 2 Non-Existant File
if (fread ( &pwad, 1 , 4, WadFile) != 4)
return FALSE;
if ( (strncmp( pwad, "PWAD", 4)) && (strncmp( pwad, "IWAD", 4)) )
return FALSE;
if (fread ( &direntries , 1 , 4, WadFile) != 4)
return FALSE;
if (fread( &dirstart, 1, 4, WadFile) != 4) /* Reads 4 byte pointer */
return FALSE;
fseek(WadFile, dirstart, 0);
while ( i++ != direntries )
{
if (fread( &name, 1, 16, WadFile) != 16 )
return FALSE;
if (doom2) //Doom 2 wad directory uses MAP01-MAP32
{
if (( name [8] == 'M' ) && ( name [9] == 'A' ) && ( name [10] == 'P'))
strcpy(levels[j++], &name[8]);
else levels[j][0]=EOS;
}
else //Doom wad directory uses E1M1-E3M9
{
if (( name [8] == 'E' ) && ( name [10] == 'M' ))
strcpy(levels[j++], &name[8]);
else levels[j][0]=EOS;
}
}
fclose(WadFile);
return TRUE;
}
void wadleveldisplay (void)
{
char line[40];
char test[55];
char ext[]=".WAD";
int i=0;
int j=0;
int done_first;
clrscr ();
printf (" Enter directory name [%s]: ", directory);
pickdirectory ();
kill_nonwads ();
cprintf ("\r\n Enter the Wadfile(s) to be scanned (separate wads with spaces)\r\n [");
printselected(5);
gets(line);
printf("\n");
if (line [0] != EOS)
parsewad ( line , ext);
i=0;
while (wadname[i][0] != EOS)
{
done_first = FALSE;
sprintf( test, "%s%s\0", directory, wadname [i++]);
if (getwadlevel( test) == TRUE)
{
printf("%s contains:\n ", test);
while ( levels[j][0] != EOS)
{
printf ("%s%s",
done_first ? ", " : "",
levels [j++]);
done_first = TRUE;
}
j=0;
printf("\n");
pause();
}
else
printf("Error reading %s", test);
printf ("\n\n");
}
}
void kill_nonwads ( void ) //removes non-wad files from the tag list
{
int i=0;
int j;
while ( wadname [i][0] != EOS )
{
if ( strncmpi(&wadname[i][ strlen(wadname[i]) - 4], ".WAD", 4) != 0)
{
for (j=i; j<9; j++)
strcpy(wadname[j], wadname[j+1]); //moves all files up 1 position
i--; // Removed a file, we need to decriment to re-check 'i'
}
i++;
}
}
int SendFile ( void )
{
struct time t;
char zipfile[13]; //Name of the Temperary Zipfile
char ziplist[9]; //Name of the Temperary PKZIP response file
char pkzip[35]; //Pkzip command line
char dsz[130]; //DSZ command line
char dszfiles[20][72]; //list of files to be 'strcat'ed to the DSZ command line
char temp[55]; //what else...a temporary variable
int i=0; //just a counter
int c;
int runzip=FALSE; //Do I run PKZIP ???
int rundsz=FALSE; //Do I run DSZ ???
int dszloops=1; //number of times to run dsz
FILE *test;
clrscr();
if (wadname [0][0] == EOS )
{
printf("No Files were selected\n"); //duhh..
pause();
return FALSE;
}
for (c=0;c<4;c++) //Initializes the files I just use a 'strcat' later
dszfiles[c][0]=EOS;
gettime(&t); //I shouldn't ever overwrite a file this way :)
sprintf(zipfile,"ID%02d%02d%02d.ZIP", t.ti_hour, t.ti_min, t.ti_sec);
sprintf(ziplist,"ID%02d%02d%02d", t.ti_hour, t.ti_min, t.ti_sec);
sprintf (pkzip,"pkzip -ex %s @%s", zipfile, ziplist);
if ((test = fopen( ziplist, "w+t" )) == NULL ) // open a pkzip list file
return FALSE;
textcolor(YELLOW);
while ( wadname[i][0] != EOS )
{
if (strncmpi( &wadname[i][ strlen(wadname[i]) - 4], ".ZIP", 4) != 0)
{ //Adds non Zipfiles to the PKZIP response file
fprintf(test, "%s%s\n", directory, wadname[i++]);
runzip=TRUE;
}
else
{ //Adds Pre Zipped files to lists for DSZ
rundsz=TRUE;
sprintf(temp, "%s%s ", directory, wadname[i++]);
if ( (strlen(dszfiles[dszloops-1]) + strlen(temp)) >= 70)
dszloops++;
strcat(dszfiles[dszloops-1], temp);
}
}
fclose(test);
if (runzip == TRUE)
{
printf("Running Pkzip......\n");
if (system ( pkzip));
if (access(zipfile, 0) == 0)
{ //Makes sure you didn't <CTRL>Break Pkzip
rundsz=TRUE;
if ( (strlen(dszfiles[dszloops-1]) + strlen(zipfile)) >= 70)
dszloops++;
strcat(dszfiles[dszloops-1], zipfile);
}
else //You must have killed PKZIP, check whether there are other files to send
if (rundsz == FALSE)
dszloops=0;
}
remove(ziplist);
if (rundsz == TRUE)
{
clrscr();
cprintf("<ALT>-N can be used to NUKE the DSZ transfer\r\n"
"but please don't unless you really screwed up :(\r\n\r\n");
}
if (dszloops > 1)
{
cprintf("Due to command line limitations with DSZ, DSZ needs to be called\r\n"
"%d times to send all flagged files. Don't worry about the\r\n"
"negotiation, I handle the whole thing. I Hope :)\r\n"
"BTW: You'll need to NUKE each call to DSZ to abort the transfer.\r\n\r\n",dszloops);
delay(1000);
}
while (dszloops >= 1)
{
sprintf(dsz,"transfer\\dsz portx %x,%i speed %lu d ha on sz -rr %s", uart, irq, baud, dszfiles[dszloops-1] );
if(system( dsz));
if (--dszloops != 0)
{
cprintf("\r\n\r\nFile set complete. Preparing for next set...\r\n");
delay(3000); //Delay for 3 seconds before writing negotiation byte
c=0x19;
write_buffer (&(char)c, 1); //Sends command to reload DSZ
}
else
{
delay(3000);
c=0x1A;
write_buffer (&(char)c, 1); //Sends command to quit
}
}
textcolor(LIGHTGRAY);
clrscr();
printf("File transfer complete.\n");
pause();
remove ( zipfile);
return TRUE;
}
int ReceiveFile ( char *ziptodir)
{
char zipfile[15];
char output[130];
char temp[50];
unsigned int i=0;
int done=FALSE;
int nextset;
int c;
struct time t;
int time;
chdir("TRANSFER");
sprintf(output,"dsz portx %x,%i speed %lu d ha on rz -rr", uart, irq, baud);
clrscr();
textcolor(YELLOW);
cprintf("<ALT>-N can be used to NUKE the DSZ transfer\r\n"
"but please don't unless you really screwed up :(\r\n\r\n");
cprintf("Press <ESC> to quit waiting.\r\n\r\nWaiting for Remote system to start sending");
while (done != TRUE)
{
while ( bioskey(1) ) //Checks for the <ESC> key
{
if ( (bioskey (0) & 0xff) == ESC)
{
printf ("\n\nTransfer aborted.\n");
while (read_byte () != -1);
chdir("..");
textcolor(LIGHTGRAY);
return FALSE;
}
}
if (i == 30000 ) //Prints dots so you know its waiting
{
textcolor(random(15) + 1); //I felt like it OK :)
i=0;
cprintf(".");
}
i++;
if ((c = read_byte ()) != -1)
{
if (c == 0x18) //check for the ZMODEM autostart
{
printf("\n");
if(system( output) );
nextset=FALSE;
gettime(&t);
time=t.ti_sec+(t.ti_min*60);
textcolor(YELLOW);
while ( nextset != TRUE)
{
c = read_byte ();
gettime(&t);
if ( ((t.ti_min*60)+t.ti_sec - time) > 20)
{
cprintf("\r\nOops, I lost the other signal....Aborting\r\n");
pause();
nextset=TRUE;
done=TRUE;
}
if (c == 0x19) //character to re-load DSZ
{
nextset = TRUE;
cprintf("\r\nDue to command line limitations with DSZ, the remote system\r\n"
"needed to re-load DSZ to send all of the files\r\n");
cprintf("\nWaiting for next group of ZIP's");
}
if (c == 0x1A) //character to quit
{
nextset=TRUE;
done=TRUE;
}
}
} // Yes they really all end here
}
}
chdir("..");
textcolor(LIGHTGRAY);
clrscr();
printf("\nFiles transfered.\n\n");
printf("Do you wish to FLAG zip's to be extracted to %s? [Yes/No/All]:", directory);
for (EVER)
{
c = tolower (getch());
switch (c)
{
case 'a' :
{
sprintf(zipfile,"transfer\\*.zip");
printf("\nRunning Pkunzip......\n");
if (mkdir( ziptodir));
sprintf(output,"pkunzip %s %s", zipfile, ziptodir);
if (system( output));
printf("\n\nDo you want to remove the Zipfiles [Yes/No]:\n");
for (EVER)
{
c = tolower (getch());
switch (c)
{
case 'y' :
sprintf(output,"del %s",zipfile);
system(output);
return TRUE;
case 'n' :
printf("\nOk, they're in the \".\\TRANSFER\\\" directory.\n");
pause();
return TRUE;
}
}
}
case 'y' :
{
strcpy(temp,ziptodir); //dir call changes dir
dir (DIR_TYPE_ZIP);
i=0;
if (mkdir( ziptodir));
while ( wadname[i][0] != EOS)
{
sprintf(output, "pkunzip %s%s %s", directory, wadname[i++], temp);
if (system( output));
}
strcpy(directory, temp); //resets the directory to zip-output
printf("\n\nDo you want to remove FLAGGED Zipfiles [Yes/No]:");
for (EVER)
{
c = tolower (getch());
switch (c)
{
case 'y' :
i=0;
while ( wadname [i][0] != EOS)
{
sprintf(zipfile,"TRANSFER\\%s",wadname[i++]);
remove (zipfile);
}
return TRUE;
case 'n' :
printf("\nOk, they're in the \".\\TRANSFER\\\" directory.\n");
pause();
return TRUE;
}
}
}
case 'n' :
{
printf("\nOK, you can just shell to DOS and do it.\n"
"Look in the \".\\TRANSFER\\\" directory for them.\n");
pause();
return TRUE;
}
}
}
}
void file_transfer ( void )
{
char line[100];
char ext[]="";
char ch;
clrscr();
if ( access("TRANSFER\\DSZ.EXE", 0) != 0)
{
printf("\a\n DSZ.EXE is not in the \".\\TRANSFER\\\" subdirectory\n"
" You must install DSZ.EXE properly before use. Please consult the\n"
" SER6.TXT for installation notes.\n\n");
pause();
clrscr();
return;
}
printf("Send or Receive [S/R]:");
ch = tolower (getch ());
switch (ch)
{
case 's' :
cprintf ("\r\n\n Enter the directory of the files to be sent [%s]: ", directory);
pickdirectory();
printf ("\r\n Enter the Files [");
printselected(19);
gets(line);
printf("\n");
if (line [0] != EOS)
parsewad ( line, ext );
if ( wadname[0][0] != EOS)
SendFile ();
break;
case 'r' :
cprintf ("\r\n\nEnter directory for zipfile extraction [%s]: ", directory);
pickdirectory();
ReceiveFile ( directory );
break;
}
InitPort (); //Re-inits the port, incase DSZ screwed with it
clrscr();
}
void dir ( int type )
{
DIR *dir;
struct dirent *ent;
char *p;
char wad[13];
char wadfiles[301][13]; //300 Files Max or qsort() pukes
char line[6];
char extension[5];
const void *a;
const void *b;
int numfiles=0;
int numflagged=0;
int i=0;
int j=0;
int k=0;
int pages;
int xpos;
int ypos;
int wildcard=0;
clrscr ();
for (i=0; i<301 ; i++) //Initialize wadfiles
wadfiles[i][0]=EOS;
wadname[0][0]=EOS;
if (type == DIR_TYPE_ZIP) //Sets the default extension & directory
{
sprintf(extension,"ZIP");
sprintf(directory, "TRANSFER\\");
line[0]=EOS;
}
else
{
sprintf(extension,"WAD");
printf("Enter file extension for search (* for all) [%s]: ",extension);
line[0]=4; //Limit to 3 chars + null
p=cgets (line);
strcpy(line, p);
}
if (line [0] == EOS )
strcpy (line, extension);
sprintf(extension,".%s",line); // Add a '.' to extension
//Check for wildcard
if ( (extension[1] == '*') && (extension[2] == EOS) )
wildcard=3; // '3' is the number that needs to be removed from the 'strncmpi' line below
if (type == DIR_TYPE_NORMAL)
{
printf ("\n Enter the directory to be displayed [%s]: ", directory);
pickdirectory ();
}
if (( dir = opendir(directory)) != NULL)
{
while( ((ent = readdir(dir)) != NULL) && (numfiles < 300 ) )
{
if (strlen(ent->d_name) > 4)
{
if (strncmpi( &ent->d_name[strlen(ent->d_name) - 4], extension, (4-wildcard)) == 0)
strcpy(wadfiles[numfiles++], ent->d_name);
}
wadfiles[numfiles][0]=EOS;
}
if (closedir(dir) != 0)
{
printf("\n\nUnable to close Directory\n\n");
pause ();
}
}
else
{
printf("\n\nUnable to open Directory\n\n");
pause ();
return;
}
/* Sorts the files */
qsort((void *)wadfiles, numfiles, sizeof(wadfiles[0]), sort_function);
pages = (numfiles / 68)+1; //68 files per page
numfiles = 0;
for ( i = 0; i < pages; i++)
{
clrscr();
printf("****** Page %i of %i of %s*%s *******\n\n",(i+1), pages, directory, extension);
for (j = (0 + numfiles); j < (68 + numfiles); )
{
for ( k = 0; k < 4; k++) // 4 columns per page
{
if (wadfiles[j][0] != EOS)
{
printf("[%3d] %+12s ", (j+1), wadfiles[j]);
j++;
}
else
{
printf("\n");
k=4;
j=68+numfiles;
}
}
}
numfiles = j;
line [0] = ' ';
cprintf("\r\nEnter the NUMBERS of the files to Flag. (20 FILES MAX)\r\n"
"Hit Enter to quit flagging or view next page\r\n"
"Files [");
printselected(7);
while ( (numflagged < 20 ) && (line[0] != EOS) )
{
xpos=wherex();
ypos=wherey();
gets(line);
gotoxy( (xpos+strlen(line)) , ypos); //Repositions cursor after linefeed
if ( line[0] != EOS)
{
printf(", ");
sscanf (line, "%d", &j);
j--;
if ( (j >= 0) && (j <= numfiles) ) //checks for a valid number
{
strcpy(wadname[numflagged],wadfiles[j]);
numflagged++;
}
}
else
printf("\n\n");
}
wadname[numflagged][0]=EOS; //Just to make sure the last entry is a EOS
}
}
int sort_function(const void *a, const void *b)
{
return( strcmp((char *)a, (char *)b) );
}
void stats (void)
{
time_t hrs;
time_t mins;
time_t secs;
struct tm *timeptr;
clrscr ();
if (starttime != 0)
{
timeptr = localtime (&starttime);
printf (" Start Time: %2d:%02d:%02d",
timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
playtime = endtime - starttime;
hrs = playtime / 3600;
mins = (playtime - (hrs * 3600)) / 60;
secs = playtime - (hrs * 3600) - (mins * 60);
printf (" Playing Time: %2d:%02d:%02d\n\n",
(int) hrs, (int) mins, (int) secs);
}
showReadStats();
showWriteStats();
showUartErrors();
}
int good_char ( int ch )
{
if ( isprint(ch) || (ch == BACKSPACE) || (ch == '\n') )
return TRUE;
else
return FALSE;
}
#define LOCAL_Y_MIN 3
#define LOCAL_Y_MAX 13
#define REMOTE_Y_MIN 15
#define REMOTE_Y_MAX 25
void split_talk (void)
{
int i;
int c;
int local_xpos=1;
int local_ypos= LOCAL_Y_MIN + 1;
int remote_xpos=1;
int remote_ypos= REMOTE_Y_MIN + 1;
int pos;
int start = 0x02; // A little bit of noise trapping
int good = FALSE;
clrscr ();
printf ("Talk mode... Press ESC to return");
gotoxy(1, LOCAL_Y_MIN - 1);
printf ("(Local)");
gotoxy(1, REMOTE_Y_MIN - 2);
/* Two lines here... 80 '=' signs plus the title. */
printf ("════════════════════════════════════════════════════════════════════════════════(Remote)");
gotoxy(local_xpos, local_ypos);
while (TRUE)
{
/* Check for keypress */
if (bioskey (1))
{
if ((c = bioskey (0) & 0xff) == ESC)
{
/* ESC key -- Exit talk mode -- Flush both sides */
while (read_byte () != -1)
;
while (bioskey (1))
bioskey (0);
clrscr();
return;
}
if (c == '\r') /* Change cr to crlf */
c = '\n';
if (good_char(c))
{
write_buffer (&(char)start, 1);
write_buffer (&(char)c, 1);
if((pos = wherey()) >= REMOTE_Y_MIN && pos <= REMOTE_Y_MAX)
{
/* We're on the remote side. Save pos. and move to local. */
remote_xpos=wherex();
remote_ypos=pos;
gotoxy(local_xpos, local_ypos);
}
printf ("%c", c);
/* If we're now in the 1st column and we didn't backspace here... */
if (( wherex() == 1) && ( c != BACKSPACE ) )
{
/* ... then we're on a new line, so increment ypos. */
local_ypos++;
/* If we're at the bottom of the local section, move to the top. */
if (wherey() == LOCAL_Y_MAX)
{
local_ypos = LOCAL_Y_MIN;
gotoxy ( 1, local_ypos);
}
/* Clear this line, and the next if not max. */
clreol();
if ( (local_ypos + 1) != LOCAL_Y_MAX )
{
gotoxy(1, local_ypos+1);
clreol();
gotoxy(1, local_ypos);
}
}
}
}
/* Check for received byte */
c = read_byte();
if( (c != -1) && (good == TRUE) )
{
good = FALSE;
if (good_char(c))
{
if ((pos = wherey()) >= LOCAL_Y_MIN && pos <= LOCAL_Y_MAX)
{
/* We're on the local side. Save pos and move to remote. */
local_xpos=wherex();
local_ypos=wherey();
gotoxy(remote_xpos, remote_ypos);
}
printf ("%c", c);
/* If we're now in the 1st column and we didn't backspace here... */
if (( wherex() == 1) && ( c != BACKSPACE ) )
{
/* ... then we're on a new line, so increment ypos. */
remote_ypos++;
/* If we're at the bottom of the remote section, move to the top. */
if (wherey () == REMOTE_Y_MAX)
{
remote_ypos = REMOTE_Y_MIN;
gotoxy ( 1, remote_ypos);
}
/* Clear this line, and the next if not max. */
clreol();
if ( (remote_ypos + 1) != REMOTE_Y_MAX )
{
gotoxy(1, remote_ypos+1);
clreol();
gotoxy(1, remote_ypos);
}
}
}
}
if (c == start)
good = TRUE;
}
}
void reset_counters (void)
{
/* showReadStats() counters. */
writeBufferOverruns = 0;
bytesRead = 0;
packetsRead = 0;
largestReadPacket = 0;
smallestReadPacket = 0xFFFFFFFFl;
readBufferOverruns = 0;
totalReadPacketBytes = 0;
oversizeReadPackets = 0;
largestOversizeReadPacket = 0;
overReadPacketLen = 0;
/* showWriteStats() counters. */
bytesWritten = 0;
packetsWrite = 0;
largestWritePacket = 0;
smallestWritePacket = 0xFFFFFFFFl;
totalWritePacketBytes = 0;
oversizeWritePackets = 0;
largestOversizeWritePacket = 0;
/* showUartErrors() counters. */
numBreak = 0;
numFramingError = 0;
numParityError = 0;
numOverrunError = 0;
numTxInterrupts = 0;
numRxInterrupts = 0;
}
void title (void)
{
clrscr();
gotoxy (1, 4);
cprintf("╔═════════════════════════╕\r\n");
cprintf("║ │\r\n");
cprintf("║ │\r\n");
cprintf("║ ├────────────┐\r\n");
cprintf("║ │ │\r\n");
cprintf("║ │ │\r\n");
cprintf("╙─────────────────────────┘ │\r\n");
cprintf(" ┌─────────────┴─────────────┐\r\n");
cprintf(" │ %4.4s │\r\n",PROG_NAME);
cprintf(" │ DOOM SERIAL DEVICE DRIVER │\r\n");
cprintf(" └─────────────┬─────────────┘\r\n");
cprintf(" │ ┌──────────────────────────╖\r");
cprintf(" │ │ ║\r");
cprintf(" │ │ ║\r");
cprintf(" └────────────┤ ║\r");
cprintf(" │ ║\r");
cprintf(" │ ║\r");
cprintf(" ╘══════════════════════════╝\r");
window(3,5,25,10);
textcolor(DARKGRAY);
DOOM();
gotoxy(55,16);
window(55,16,77,21);
textcolor(GREEN);
DOOM();
window(1,1,80,25);
textcolor(LIGHTGRAY);
gotoxy(1,25);
pause ();
}
void DOOM (void)
{
cprintf("▄▄▄▄ ▄▄▄ ▄▄▄ ▄ ▄\r");
cprintf("█ █ █ █ █ █ ██▄██\r");
cprintf("█ █ █ █ █ █ █ ▀ █\r");
cprintf("█ █ █ █ █ █ █ █\r");
cprintf("▀▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀\r");
}
void shell (void)
{
char comspec[30];
char oldprompt[128];
static char prompt[128]; //setenv requires a static or global
char path[80];
int drive;
cprintf("\n\nDos Shell......\n\n");
drive=getdisk();
strcpy(path, "X:\\"); /* fill string with form of response: X:\ */
path[0] = 'A' + getdisk(); /* replace X with current drive letter */
getcurdir(0, path+3); /* fill rest of string with current directory */
strcpy(oldprompt,getenv("PROMPT"));
sprintf(prompt,"PROMPT=Type 'EXIT' to return to %s$_%.80s",
PROG_NAME, oldprompt);
putenv(prompt);
strcpy(comspec,getenv("COMSPEC"));
if (comspec != NULL)
spawnv(P_WAIT,comspec,NULL);
else //Just incase someone looses the COMSPEC env variable
{
printf("\nEnvironment Variable COMSPEC was not found!\nAssuming Command.Com\n");
spawnvp(P_WAIT,"COMMAND.COM",NULL);
}
sprintf(prompt,"PROMPT=%.100s",oldprompt); //resets environment
putenv(prompt);
setdisk(drive); //returns to the DOOM dir.
chdir(path);
clrscr();
}
int promptdropdtr( void )
{
char ch;
printf("\n\nExit and Hangup the modem (Y)\n"
"Exit and Leave DTR up (X)\n"
"Go Back to Main Menu (N):");
while(1)
{
ch = getch();
tolower(ch);
switch(ch)
{
case 'y':
nodropdtr = FALSE;
printf("\n\n");
return TRUE;
case 'n':
printf("\n\n");
return FALSE;
case 'x':
nodropdtr = TRUE;
printf("\n\n");
return TRUE;
default :
break;
}
}
}
void pause (void)
{
printf("Press any key to continue...");
getch();
}
void usage (void)
{
clrscr ();
printf (
"\n\n\n\n\n%s is run without arguments. Just type \"%s\"\n\n",
PROG_EXE, PROG_NAME);
printf (
"To change port-related settings, edit the %s file,\n", PROG_CONFIG);
printf (
"and to change game settings, use the CONFIGURE option while running.\n\n"
"Yes, this means setup.exe won't work, but don't sweat the small stuff. :-)\n\n");
pause ();
}
/*
=================
=
= main
=
=================
*/
void main(void)
{
int ch;
if (_argc > 1)
usage ();
title();
/* Setup the struct that we'll use to communicate with doom (via interrupt)*/
doomcom.extratics = 1; /* Make "extratics" default, it runs better. */
doomcom.id = DOOMCOM_ID; /* Used to verify that doomcom struct is ok. */
doomcom.ticdup = 1;
doomcom.numnodes = 2; /* Don't waste your time trying 3 or 4. */
doomcom.numplayers = 2; /* Don't waste your time trying 3 or 4. */
doomcom.drone = 0;
doomcom.consoleplayer = 0; /* Default - may be overridden later. */
get_config_settings (); /* Read config file and get uart & vector. */
InitPort (); /* Initialize the port. */
print_config_settings (); /* Print out current settings. */
while (read_byte() != -1) /* Flush any old stuff from uart buffer */
;
/* Get connected to the other computer. */
while (TRUE)
{
printf ("\nSelect: [D] Dial [A] Answer [C] Connected already [Q] Quit\n"
" [U] Use Alternate BAUD and INIT");
ch = tolower (getch ());
printf ("\n");
if (ch == 'd')
{
if (Dial_Modem ())
break;
}
else if (ch == 'a')
{
if (Answer ())
break;
}
else if (ch == 'q')
Error (NULL);
else if (ch == 'u')
alt_init ();
else if (ch == 'c')
break;
}
/* Main menu. */
clrscr();
while (TRUE)
{
cprintf (
" Main Menu\r\n\n");
cprintf (
" [D] Play Doom [C] Configure [T] Talk to Remote [Q] Quit\r\n"
" [F] File Dir [W] Wad Levels [Z] Zmodem File Xfer\r\n"
" [S] Serial Stats [!] DOS Shell\r\n");
ch = tolower (getch ());
printf ("\n");
switch (ch)
{
case 'd' :
if (Connect ())
{
reset_counters ();
time (&starttime);
if (doomver1_2 == 1)
LaunchDOOM1_2 ();
else
LaunchDOOM ();
time (&endtime);
}
break;
case 's' :
stats ();
break;
case 'c' :
configure ();
break;
case 't' :
split_talk ();
break;
case 'q' :
if (promptdropdtr() == TRUE)
Error (NULL);
break;
case '!' :
shell ();
break;
case 'w' :
wadleveldisplay ();
clrscr();
break;
case 'z' :
file_transfer();
break;
case 'f' :
dir (DIR_TYPE_NORMAL);
clrscr();
break;
}
}
}